package capricornus.utils
{
	import flash.display.DisplayObject;
	import flash.geom.Matrix;
	import flash.geom.Point;

	public class PointUtils
	{
		public static function angleToRadian( angle:Number ):Number
		{
			return angle * Math.PI/180;
		}
		
		public static function radianToAngle( radian:Number ):Number
		{
			return radian * 180/Math.PI;
		}
		
		/**
		 * 获取两个点([x0,y0] ~ [x1,y1])之间的长度， 
		 * @param arr0
		 * @param arr1
		 * @return 长度
		 * 
		 */		
		public static function getLength( arr0:Array, arr1:Array ):Number
		{
			var x:Number = arr0[0] - arr1[0];
			var y:Number = arr0[1] - arr1[1];
			
			return Math.sqrt( x * x + y * y );
		}
		
		/**
		 * 确定两个指定点之间的点。 参数 len确定新的内插点相对于参数 from 和 to 指定的两个端点所处的位置。 参数 len的值越接近 length，则内插点就越接近第二个点（参数 to）。 参数len的值越接近 0，则内插点就越接近第一个点（参数 from）。  
		 * @param from 第一个点
		 * @param to 第二个点
		 * @param len 两个点之间的内插值
		 * @param length 两点之间的长度，可不传
		 * @return 新的内插点。
		 * 
		 */		
		public static function interpolate2( from:Array, to:Array, len:Number, length:int=-1 ):Array
		{
			if( length==-1 )
			{
				length = getLength( from, to );
			}
			var x:Number = to[0] - from[0];
			var y:Number = to[1] - from[1];
			if( length==0 )
			{
				return [from[0], from[1]];
			}
			else
			{
				x = x / length * len + from[0];
				y = y / length * len + from[1];
			}
			return [x, y];
		}
		
		/**
		 * 判断arrJudge是否在arr0与arr1的连线上，是则返回true，否则返回false 
		 * @param arr0
		 * @param arr1
		 * @param arrJudge  要判断的点
		 * @return Boolean
		 * 
		 */		
		public static function isInSameLine( arr0:Array, arr1:Array, arrJudge:Array ):Boolean
		{
			var x:Number = arr1[0] - arr0[0];
			if( x==0 )
			{
				return arrJudge[0]==arr0[0];
			}
			var y:Number = arr1[1] - arr0[1];
			
			var xj:Number = arrJudge[0] - arr0[0];
			if( xj==0 ) return false;
			return (arrJudge[1] - arr0[1])/xj==y/x;
		}
		
		/**
		 * 判断arrJudge是否在arr0指向arr1的连线方向上，如果是则返回true，否则返回false 
		 * @param arr0
		 * @param arr1
		 * @param arrJudge
		 * @return 
		 * 
		 */		
		public static function isInSameDirectLine( arr0:Array, arr1:Array, arrJudge:Array ):Boolean
		{
			var x:Number = arr1[0] - arr0[0];
			var y:Number = arr1[1] - arr0[1];
			
			var xj:Number = arrJudge[0] - arr0[0];
			var y2:Number = arrJudge[1] - arr0[1];
			
			if( x==0 )
			{
				if( xj==0 )
				{
					if( (y2>=0 && y>=0) || (y2<0 && y<0) ) return true;
					return false;
				}
				else
				{
					return false;
				}
			}
			if( xj==0 ) return false;
			
			if( y2/xj==y/x )
			{
				if( (y2>=0 && y>=0) || (y2<0 && y<0) ) return true;
				return false;
			}
			return false;
		}
		
		/**
		 * 获得由arr0指向arr1组成的向量与x轴的夹角 
		 * @param arrFrom
		 * @param arrTo
		 * @return 弧度      注意：这个角度是以屏幕坐标系为标准的
		 * 
		 */		
		public static function getLineRadian( arrFrom:Array, arrTo:Array ):Number
		{
			return getPointRadian( new Point( arrTo[0]-arrFrom[0], arrTo[1]-arrFrom[1] ) );
		}
		
		/**
		 * 获取点与（0，0）点的夹角 
		 * @param pt
		 * @return  弧度   注意：这个角度是以屏幕坐标系为标准的
		 * 
		 */		
		public static function getPointRadian( pt:Point ):Number
		{
			var len:Number = pt.length;
			if( len==0 )
			{
				return 0;
			}
			var radian:Number = Math.acos( pt.x/len );
			if( pt.y < 0 )
			{
				radian = 2 * Math.PI - radian;
			}
			return radian;
		}
		
		/**
		 * 获得两点与原点的夹角 
		 * @param pt1
		 * @param pt2
		 * @return 
		 * 
		 */		
		public static function getPointToPointRadian( pt1:Point, pt2:Point ):Number
		{
			return getPointRadian( new Point(pt2.x-pt1.x, pt2.y-pt1.y) );
		}
		
		/**
		 * 
		 * @param pt 要旋转的点
		 * @param radian 旋转弧度
		 * @return 返回旋转后的点
		 * 
		 */		
		public static function rotatePoint( pt:Point, radian:Number ):Point
		{
			var len:Number = pt.length;
			radian += getPointRadian(pt);
			return new Point( len*Math.cos(radian), -len*Math.sin(radian) );
		}
		
		/**
		 * 以pt1至pt2为方向 旋转target, target以水平向右为原方向
		 * @param target
		 * @param pt1
		 * @param pt2
		 * 
		 */		
		public static function rotatePointToPoint( target:DisplayObject, from:Point, to:Point ):void
		{
			var mt:Matrix = rotateToPointMatrix( from, to );
			mt.tx = target.x;
			mt.ty = target.y;
			target.transform.matrix = mt; 
		}
		
		/**
		 * 与rotatePointToPoint功能相同
		 */		
		public static function rotatePointToPoint2( target:DisplayObject, from:Array, to:Array ):void
		{
			rotatePointToPoint( target, new Point( from[0], from[1] ), new Point( to[0], to[1] ) );
		}
		
		//由pt1 指向 pt2
		private static function rotateToPointMatrix( pt1:Point, pt2:Point ):Matrix
		{
			var fLen:Number = Point.distance( pt1, pt2 );
			
			var mt:Matrix = new Matrix();
			
			if( fLen )
			{
				var x:Number = pt2.x - pt1.x;
				var y:Number = pt2.y - pt1.y;
				var sin:Number = y / fLen;
				var cos:Number = x / fLen;
				
				mt.a = cos;
				mt.b = sin;
				mt.c = -sin;
				mt.d = cos;
			}
			
			return mt;
		} 
		
		
		public function PointUtils()
		{
		}
	}
}